home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Zoners Half-Life Tools / hlrad / vismatrix.cpp < prev    next >
C/C++ Source or Header  |  2002-12-09  |  13KB  |  399 lines

  1. #include "qrad.h"
  2.  
  3. ////////////////////////////
  4. // begin old vismat.c
  5. //
  6. #define    HALFBIT
  7.  
  8. // =====================================================================================
  9. //
  10. //      VISIBILITY MATRIX
  11. //      Determine which patches can see each other
  12. //      Use the PVS to accelerate if available
  13. //
  14. // =====================================================================================
  15.  
  16. static byte*    s_vismatrix;
  17.  
  18.  
  19.  
  20. #ifdef HLRAD_HULLU
  21. // =====================================================================================
  22. //      OPACITY ARRAY
  23. // =====================================================================================
  24.  
  25. typedef struct {
  26.     unsigned bitpos;
  27.     vec3_t transparency;
  28. } transparency_t;
  29.  
  30. static transparency_t *s_transparency_list = NULL;
  31. static unsigned long s_transparency_count = 0;
  32. static unsigned long s_max_transparency_count=0;
  33.  
  34. static void FindOpacity(const unsigned bitpos, vec3_t &out)
  35. {
  36.     for(unsigned long i = 0; i < s_transparency_count; i++)
  37.     {
  38.         if( s_transparency_list[i].bitpos == bitpos )
  39.         {
  40.             VectorCopy(s_transparency_list[i].transparency, out);
  41.             return;
  42.         }
  43.     }
  44.     VectorFill(out, 1.0);
  45. }
  46.  
  47. #endif /*HLRAD_HULLU*/
  48.  
  49. // =====================================================================================
  50. //  TestPatchToFace
  51. //      Sets vis bits for all patches in the face
  52. // =====================================================================================
  53. static void     TestPatchToFace(const unsigned patchnum, const int facenum, const int head, const unsigned int bitpos)
  54. {
  55.     patch_t*        patch = &g_patches[patchnum];
  56.     patch_t*        patch2 = g_face_patches[facenum];
  57.  
  58.     // if emitter is behind that face plane, skip all patches
  59.  
  60.     if (patch2)
  61.     {
  62.         const dplane_t* plane2 = getPlaneFromFaceNumber(facenum);
  63.  
  64.         if (DotProduct(patch->origin, plane2->normal) > (PatchPlaneDist(patch2) + MINIMUM_PATCH_DISTANCE))
  65.         {
  66.             // we need to do a real test
  67.             const dplane_t* plane = getPlaneFromFaceNumber(patch->faceNumber);
  68.  
  69.             for (; patch2; patch2 = patch2->next)
  70.             {
  71.                 unsigned        m = patch2 - g_patches;
  72.  
  73. #ifdef HLRAD_HULLU
  74.         vec3_t         transparency = {1.0, 1.0, 1.0};
  75. #endif
  76.         
  77.                 // check vis between patch and patch2
  78.                 // if bit has not already been set
  79.                 //  && v2 is not behind light plane
  80.                 //  && v2 is visible from v1
  81.                 if (m > patchnum
  82.                     && (DotProduct(patch2->origin, plane->normal) > (PatchPlaneDist(patch) + MINIMUM_PATCH_DISTANCE))
  83.                     && (TestLine_r(head, patch->origin, patch2->origin) == CONTENTS_EMPTY)
  84. #ifdef HLRAD_HULLU
  85.                     && (!TestSegmentAgainstOpaqueList(patch->origin, patch2->origin, transparency)))
  86. #else
  87.                     && (!TestSegmentAgainstOpaqueList(patch->origin, patch2->origin)))
  88. #endif
  89.                 {
  90.                     //Log("SDF::3\n");
  91.  
  92.                     // patchnum can see patch m
  93.                     unsigned        bitset = bitpos + m;
  94.  
  95. #ifdef HLRAD_HULLU
  96.                     // transparency face fix table
  97.                     // TODO: this method makes MakeScale extreamly slow.. find new one
  98.  
  99.                     if(g_customshadow_with_bouncelight && fabs(VectorAvg(transparency) - 1.0) < 0.001)
  100.                     {
  101.                         while(s_transparency_count >= s_max_transparency_count)
  102.                         {
  103.                             //new size
  104.                             unsigned long old_max = s_max_transparency_count;
  105.                             s_max_transparency_count += 128;
  106.                             
  107.                             //realloc
  108.                             s_transparency_list = (transparency_t*)realloc(s_transparency_list, s_max_transparency_count * sizeof(transparency_t));
  109.                             
  110.                             // clean new memory
  111.                             memset(&s_transparency_list[old_max], 0, sizeof(transparency_t) * 128);
  112.                         }
  113.                         
  114.                         //add to array
  115.                         VectorCopy(transparency, s_transparency_list[s_transparency_count].transparency);
  116.                         s_transparency_list[s_transparency_count].bitpos = bitset;
  117.  
  118.                         s_transparency_count++;
  119.                     }
  120. #endif /*HLRAD_HULLU*/
  121.  
  122.                     s_vismatrix[bitset >> 3] |= 1 << (bitset & 7);
  123.                 }
  124.             }
  125.         }
  126.     }
  127. }
  128.  
  129. // =====================================================================================
  130. //  BuildVisRow
  131. //      Calc vis bits from a single patch
  132. // =====================================================================================
  133. static void     BuildVisRow(const int patchnum, byte* pvs, const int head, const unsigned int bitpos)
  134. {
  135.     int             j, k, l;
  136.     byte            face_tested[MAX_MAP_FACES];
  137.     dleaf_t*        leaf;
  138.  
  139.     memset(face_tested, 0, g_numfaces);
  140.  
  141.     // leaf 0 is the solid leaf (skipped)
  142.     for (j = 1, leaf = g_dleafs + 1; j < g_numleafs; j++, leaf++)
  143.     {
  144.         if (!(pvs[(j - 1) >> 3] & (1 << ((j - 1) & 7))))
  145.             continue;                                      // not in pvs
  146.         for (k = 0; k < leaf->nummarksurfaces; k++)
  147.         {
  148.             l = g_dmarksurfaces[leaf->firstmarksurface + k];
  149.  
  150.             // faces can be marksurfed by multiple leaves, but
  151.             // don't bother testing again
  152.             if (face_tested[l])
  153.                 continue;
  154.             face_tested[l] = 1;
  155.  
  156.             TestPatchToFace(patchnum, l, head, bitpos);
  157.         }
  158.     }
  159. }
  160.  
  161. // =====================================================================================
  162. // BuildVisLeafs
  163. //      This is run by multiple threads
  164. // =====================================================================================
  165. #ifdef SYSTEM_WIN32
  166. #pragma warning(push)
  167. #pragma warning(disable: 4100)                             // unreferenced formal parameter
  168. #endif
  169. static void     BuildVisLeafs(int threadnum)
  170. {
  171.     int             i;
  172.     int             lface, facenum, facenum2;
  173.     byte            pvs[(MAX_MAP_LEAFS + 7) / 8];
  174.     dleaf_t*        srcleaf;
  175.     dleaf_t*        leaf;
  176.     patch_t*        patch;
  177.     int             head;
  178.     unsigned        bitpos;
  179.     unsigned        patchnum;
  180.  
  181.     while (1)
  182.     {
  183.         //
  184.         // build a minimal BSP tree that only
  185.         // covers areas relevent to the PVS
  186.         //
  187.         i = GetThreadWork();
  188.         if (i == -1)
  189.             break;
  190.         i++;                                               // skip leaf 0
  191.         srcleaf = &g_dleafs[i];
  192.         DecompressVis(&g_dvisdata[srcleaf->visofs], pvs, sizeof(pvs));
  193.         head = 0;
  194.  
  195.         //
  196.         // go through all the faces inside the
  197.         // leaf, and process the patches that
  198.         // actually have origins inside
  199.         //
  200.         for (lface = 0; lface < srcleaf->nummarksurfaces; lface++)
  201.         {
  202.             facenum = g_dmarksurfaces[srcleaf->firstmarksurface + lface];
  203.             for (patch = g_face_patches[facenum]; patch; patch = patch->next)
  204.             {
  205.                 leaf = PointInLeaf(patch->origin);
  206.                 if (leaf != srcleaf)
  207.                     continue;
  208.  
  209.                 patchnum = patch - g_patches;
  210.  
  211. #ifdef HALFBIT
  212.                 bitpos = patchnum * g_num_patches - (patchnum * (patchnum + 1)) / 2;
  213. #else
  214.                 bitpos = patchnum * g_num_patches;
  215. #endif
  216.                 // build to all other world leafs
  217.                 BuildVisRow(patchnum, pvs, head, bitpos);
  218.  
  219.                 // build to bmodel faces
  220.                 if (g_nummodels < 2)
  221.                     continue;
  222.                 for (facenum2 = g_dmodels[1].firstface; facenum2 < g_numfaces; facenum2++)
  223.                     TestPatchToFace(patchnum, facenum2, head, bitpos);
  224.             }
  225.         }
  226.  
  227.     }
  228. }
  229.  
  230. #ifdef SYSTEM_WIN32
  231. #pragma warning(pop)
  232. #endif
  233.  
  234. // =====================================================================================
  235. // BuildVisMatrix
  236. // =====================================================================================
  237. static void     BuildVisMatrix()
  238. {
  239.     int             c;
  240.  
  241. #ifdef HALFBIT
  242.     c = ((g_num_patches + 1) * (g_num_patches + 1)) / 16;
  243. #else
  244.     c = g_num_patches * ((g_num_patches + 7) / 8);
  245. #endif
  246.  
  247.     Log("%-20s: %5.1f megs\n", "visibility matrix", c / (1024 * 1024.0));
  248.  
  249.     s_vismatrix = (byte*)AllocBlock(c);
  250.  
  251.     if (!s_vismatrix)
  252.     {
  253.         Log("Failed to allocate s_vismatrix");
  254.         hlassume(s_vismatrix != NULL, assume_NoMemory);
  255.     }
  256.  
  257.     NamedRunThreadsOn(g_numleafs - 1, g_estimate, BuildVisLeafs);
  258. }
  259.  
  260. static void     FreeVisMatrix()
  261. {
  262.     if (s_vismatrix)
  263.     {
  264.         if (FreeBlock(s_vismatrix))
  265.         {
  266.             s_vismatrix = NULL;
  267.         }
  268.         else
  269.         {
  270.             Warning("Unable to free s_vismatrix");
  271.         }
  272.     }
  273.  
  274. #ifdef HLRAD_HULLU
  275.     if(s_transparency_list)
  276.     {
  277.         free(s_transparency_list);
  278.         s_transparency_list = NULL;
  279.     }
  280.     s_transparency_count = s_max_transparency_count = 0;
  281. #endif
  282.  
  283. }
  284.  
  285. // =====================================================================================
  286. // CheckVisBit
  287. // =====================================================================================
  288. #ifdef HLRAD_HULLU
  289. static bool     CheckVisBitVismatrix(unsigned p1, unsigned p2, vec3_t &transparency_out)
  290. #else
  291. static bool     CheckVisBitVismatrix(unsigned p1, unsigned p2)
  292. #endif
  293. {
  294.     unsigned        bitpos;
  295.  
  296.     if (p1 > p2)
  297.     {
  298.         const unsigned a = p1;
  299.         const unsigned b = p2;
  300.         p1 = b;
  301.         p2 = a;
  302.     }
  303.  
  304.     if (p1 > g_num_patches)
  305.     {
  306.         Warning("in CheckVisBit(), p1 > num_patches");
  307.     }
  308.     if (p2 > g_num_patches)
  309.     {
  310.         Warning("in CheckVisBit(), p2 > num_patches");
  311.     }
  312.  
  313. #ifdef HALFBIT
  314.     bitpos = p1 * g_num_patches - (p1 * (p1 + 1)) / 2 + p2;
  315. #else
  316.     bitpos = p1 * g_num_patches + p2;
  317. #endif
  318.  
  319.     if (s_vismatrix[bitpos >> 3] & (1 << (bitpos & 7)))
  320.     {
  321. #ifdef HLRAD_HULLU        
  322.         if(g_customshadow_with_bouncelight)
  323.         {
  324.             vec3_t getvalue = {1.0, 1.0, 1.0};
  325.             FindOpacity(bitpos, getvalue);
  326.             VectorCopy(getvalue, transparency_out);
  327.         }
  328.         else
  329.         {
  330.             VectorFill(transparency_out, 1.0);
  331.         }
  332. #endif
  333.         return true;
  334.     }
  335.  
  336. #ifdef HLRAD_HULLU
  337.     VectorFill(transparency_out, 0.0);
  338. #endif
  339.  
  340.     return false;
  341. }
  342.  
  343. //
  344. // end old vismat.c
  345. ////////////////////////////
  346.  
  347. // =====================================================================================
  348. // MakeScalesVismatrix
  349. // =====================================================================================
  350. void            MakeScalesVismatrix()
  351. {
  352.     char            transferfile[_MAX_PATH];
  353.  
  354.     hlassume(g_num_patches < MAX_VISMATRIX_PATCHES, assume_MAX_PATCHES);
  355.  
  356.     safe_strncpy(transferfile, g_source, _MAX_PATH);
  357.     StripExtension(transferfile);
  358.     DefaultExtension(transferfile, ".inc");
  359.  
  360.     if (!g_incremental || !readtransfers(transferfile, g_num_patches))
  361.     {
  362.         // determine visibility between g_patches
  363.         BuildVisMatrix();
  364.         g_CheckVisBit = CheckVisBitVismatrix;
  365.  
  366. #ifdef HLRAD_HULLU
  367.         if((s_max_transparency_count*sizeof(transparency_t))>=(1024 * 1024))
  368.             Log("%-20s: %5.1f megs\n", "custom shadow array", (s_max_transparency_count*sizeof(transparency_t)) / (1024 * 1024.0));
  369.         else if(s_transparency_count)
  370.             Log("%-20s: %5.1f kilos\n", "custom shadow array", (s_max_transparency_count*sizeof(transparency_t)) / 1024.0);
  371. #endif
  372.  
  373. #ifndef HLRAD_HULLU
  374.         NamedRunThreadsOn(g_num_patches, g_estimate, MakeScales);
  375. #else
  376.     if(g_rgb_transfers)
  377.         {NamedRunThreadsOn(g_num_patches, g_estimate, MakeRGBScales);}
  378.     else
  379.         {NamedRunThreadsOn(g_num_patches, g_estimate, MakeScales);}
  380. #endif
  381.         FreeVisMatrix();
  382.  
  383.         // invert the transfers for gather vs scatter
  384. #ifndef HLRAD_HULLU
  385.         NamedRunThreadsOnIndividual(g_num_patches, g_estimate, SwapTransfers);
  386. #else
  387.     if(g_rgb_transfers)
  388.         {NamedRunThreadsOnIndividual(g_num_patches, g_estimate, SwapRGBTransfers);}
  389.     else
  390.         {NamedRunThreadsOnIndividual(g_num_patches, g_estimate, SwapTransfers);}
  391. #endif
  392.         if (g_incremental)
  393.             writetransfers(transferfile, g_num_patches);
  394.         else
  395.             unlink(transferfile);
  396.         DumpTransfersMemoryUsage();
  397.     }
  398. }
  399.